package com.zyl.blog.common.config;

import com.zyl.blog.common.service.ITreeNode;
import lombok.Data;

import java.io.Serializable;
import java.util.Comparator;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * @version v1.0
 * @ProjectName: Personal_Blog
 * @Package: com.zyl.common.config
 * @ClassName: TreeConfig
 * @Description: 树配置
 * @Author FinalFantasy
 * @Date 2025/2/19-10:01
 */
@Data
public class TreeConfig<T extends Serializable, ID> {
    // 根节点判断
    private Predicate<ITreeNode<ID>> rootPredicate = node -> node.getParentId() == null;

    // 排序
    private Comparator<ITreeNode<T>> comparator;

    // 循环判断
    private boolean checkCyclic = true;

    // 并行
    private boolean parallel = false;

    // 获取ID、父ID、子节点、设置子节点、排序
    private final Function<T, ID> idGetter;
    private final Function<T, ID> parentIdGetter;
    private final Function<T, List<T>> childrenGetter;
    private final BiConsumer<T, List<T>> childrenSetter;
    private final Comparator<T> comparators;

    // 获取ID、父ID、子节点、设置子节点、排序（使用泛型ID）
    private TreeConfig(Function<T, ID> idGetter,
                       Function<T, ID> parentIdGetter,
                       Function<T, List<T>> childrenGetter,
                       BiConsumer<T, List<T>> childrenSetter,
                       Comparator<T> comparator) {
        this.idGetter = idGetter;
        this.parentIdGetter = parentIdGetter;
        this.childrenGetter = childrenGetter;
        this.childrenSetter = childrenSetter;
        this.comparators = comparator;
    }

    /**
     * 创建树配置实例
     * @param idGetter 获取ID的函数
     * @param parentIdGetter 获取父ID的函数
     * @param childrenGetter 获取子节点的函数
     * @param childrenSetter 设置子节点的函数
     * @param comparator 排序器
     * @return 树配置实例
     * @param <T> 节点类型
     * @param <ID> ID类型（可以是任意数字类型或其他类型）
     */
    public static <T extends Serializable, ID> TreeConfig<T, ID> of(
            Function<T, ID> idGetter,
            Function<T, ID> parentIdGetter,
            Function<T, List<T>> childrenGetter,
            BiConsumer<T, List<T>> childrenSetter,
            Comparator<T> comparator) {
        return new TreeConfig<>(
                idGetter,
                parentIdGetter,
                childrenGetter,
                childrenSetter,
                comparator
        );
    }
}